home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Sound Cards
/
Programming Sound Cards.iso
/
sound_52
/
bendlib.ma
< prev
next >
Wrap
Text File
|
1995-01-01
|
17KB
|
598 lines
#
# bendlib.ma - (dx7) pitch bend library of Ravel routines
#
# Implementation Assumptions:
#
# 1. Setup for dx7 type instrument.
# might work elsewhere as is but may take some changes.
#
# 2. check SEMITONEUNITS; i.e., no of pitch bend
# units per semitone. We set poff to 1.
#
# 3. Assume that
# dx7 is setup as follows:
# range 12 (an octave span for the bend)
# step 0 - continuous bend (not semitones)
#
# Functions supported:
##############################################################
# 1. riff bendUp(firstNote, firstTime, bendTime, totalTime, interval, velocity, vibrattoFlag, vibrattoSteps)
# pitch bend up of interval of 1-12 semitones
# 2. riff bendDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vibrattoFlag, vibrattoSteps)
# pitch bend down of interval of 1-12 semitones
# 3. riff bendUpDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vibrattoFlag, vibrattoSteps)
# pitch bend up then down
# 4. riff vibratto(note, bendTime, totalTime, vibrattoStep, velocity)
# vibrato on specified note
#
# There are also some test routines.
# They are at the bottom of the module. They are setup as riffs.
# They can function as examples of how to use the above riffs.
# bend units per semi-tone
SEMITONEUNITS = 680
# bend units per whole-tone
WHOLETONEUNITS = 1360
# bend units at pitchbend center
BENDCENTER = 8192
#
# vibratto - play vibratto around requested tone.
#
# time is broken up into two parts, bendTime and remainder.
# bendTime comes first. This permits vibratto followed by
# normal non-vibratto tone.
#
# vibrattoStep - range of bend around center tone.
# 10 - minimum
# 60 - medium
# 100 - heavy
#
riff vibratto(firstNote, bendTime, totalTime, vibrattoStep, velocity)
# interval - number of semitones to bend up
int events
int bendIncrement
int curincrement
int bendvalue
int elapsedTime
int remainingTime
# make sure pitch bend offset is set at 1 so
# that we use the true MIDI numbers in decimal
poff 1
bendIncrement = vibrattoStep
# play note with 0 eventime
# the note lasts "totalTime" time before a noteoff
# is issued
note firstNote 0,totalTime velocity
bendvalue = BENDCENTER
# start off with pitch bend wheel centered
# take no time to do this
bend 0 BENDCENTER
# loop through pitch bend up
elapsedTime = 0
for ( events = 0; events < bendTime; events++)
# alternate up/down around pitch
if ({events % 2} == 0)
bend 1 BENDCENTER+bendIncrement
else
bend 1 BENDCENTER-bendIncrement
end
elapsedTime++
end
# issue another pitch bend to make sure we
# arrived where we want because for loop
# above may not have arrived precisely
bend 0 BENDCENTER
# use bend constant to return pitchbend wheel to center
poff 1
# deterime amount of eventtime remaining
# we may have some slop if the amount of time
# spent playing bends did not equal the bendTime
if (elapsedTime == bendTime)
remainingTime = totalTime - bendTime
else
remainingTime = {bendTime - elapsedTime} + {totalTime - bendTime}
end
# tie note for remaining time
tie remainingTime
# void printf("bend %d \n",BENDCENTER)
# issue rest to make sure noteoff in effect. this
# is paranoia most likely
rest 0
# put pitchbend wheel at center
bend 0 BENDCENTER
# void dumptime()
end
#
# vnonote - play vibratto around requested tone. Used
# by other bend routines. Does not issue initial note.
# Also assumes that we do pitch bend for entire totalTime.
# I.e., not broken up into pitch bend, no pitch bend step.
#
# vibrattoStep - range of bend around center tone.
# 10 - minimum
# 60 - medium
# 100 - heavy
#
riff vnonote(firstNote, curbend, totalTime, vibrattoStep, velocity)
# interval - number of semitones to bend up
int events
int bendvalue
int bendIncrement
int elapsedTime
int remainingTime
# make sure pitch bend offset is set at 1 so
# that we use the true MIDI numbers in decimal
poff 1
bendIncrement = vibrattoStep
bendvalue = curbend
# loop through pitch bend up
for ( events = 0; events < totalTime; events++)
# alternate up/down around pitch
if ({events % 2} == 0)
bend 1 bendvalue+bendIncrement
else
bend 1 bendvalue-bendIncrement
end
end
# issue another pitch bend to make sure we
# arrived where we want because for loop
# above may not have arrived precisely
bend 0 bendvalue
# issue rest to make sure noteoff in effect. this
# is paranoia most likely
rest 0
# void dumptime()
bend 0 BENDCENTER
end
#
# bendUp according to specified interval.
#
# Eventtime is broken up according to following scheme.
#
# 1. issue note for firstTime events
# 2. bend for bendTime events
# 3. tie for remaining time (totalTime - (firstTime + bendTime)
# Latter non-bend time may have vibratto attached.
#
# e.g.,
# C, e, e, q, 2, 100, 0, 0
#
# would mean play C for e events, then bend to D for e events,
# and quit with no vibratto at end.
#
# firstnote - starting note
# firstTime - time devoted to first note before bend
# bendTime - period of time for bends
# totalTime - total elapsed time for note to note. If totalTime
# is larger than bendTime, we do the pitch bend first
# and spend the remaining amount of time on the note.
# interval - 1..12 semitones.
# velocity - desired velocity.
# vibratto - flag, 1 for TRUE, 0 for FALSE, if specified
# then we use vibratto for last totalTime-bendTime period.
# This permits more guitar-like effects.
# vibrattoStep - how much pitch bend for vibratto
#
# bendUp(C, 0, h, w, 12, 100, 0, 0)
# would execute a linear bend from C to HC for the first 'h'
# of time, and then execute the HC for the 2nd 'h' with
# total elapsed time of 'w'.
#
# Algorithm needs work but this gets the job done.
#
riff bendUp(firstNote, firstTime, bendTime, totalTime, interval, velocity, vflag, vsteps)
# interval - number of semitones to bend up
int events
int bendIncrement
int totalBendUnits
int pertimeClick
int curincrement
int bendvalue
int elapsedTime
int remainingTime
# make sure pitch bend offset is set at 1 so
# that we use the true MIDI numbers in decimal
poff 1
# don't set interval to 0
if (interval == 0)
void printf("bendUp: invalid 0 interval\n")
final
end
# total number of bend units to cover interval
totalBendUnits = interval * SEMITONEUNITS
# determine per bend event time and how much
# to bend per bend call
# if more time than total bend units according
# to the interval, then divide the time
# by the number of bend units to get the per
# bend call time, otherwise time is 1
if (bendTime > totalBendUnits)
pertimeClick = bendTime / totalBendUnits
bendIncrement = totalBendUnits / pertimeClick
else
bendIncrement = totalBendUnits / bendTime
pertimeClick = 1
end
# void printf("bendIncrement %d\n",bendIncrement)
# void printf("pertimeClick %d\n",pertimeClick)
# void printf("totalBendUnits %d\n",totalBendUnits)
# play note with 0 eventime
# the note lasts "totalTime" time before a noteoff
# is issued
note firstNote firstTime,totalTime velocity
# void dumptime()
bendvalue = BENDCENTER
# start off with pitch bend wheel centered
# take no time to do this
poff 1
bend 0 BENDCENTER
curincrement = bendIncrement
# loop through pitch bend up
elapsedTime = 0
for ( events = 0; events < bendTime; events++)
bend pertimeClick BENDCENTER+curincrement
# void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
curincrement = curincrement + bendIncrement
elapsedTime = elapsedTime + pertimeClick
end
# issue another pitch bend to make sure we
# arrived where we want because for loop
# above may not have arrived precisely
bend 0 BENDCENTER + totalBendUnits
# use bend constant to return pitchbend wheel to center
poff 1
# deterime amount of eventtime remaining
# we may have some slop if the amount of time
# spent playing bends did not equal the bendTime
if (elapsedTime == bendTime)
remainingTime = totalTime - {firstTime + bendTime}
else
remainingTime = {bendTime - elapsedTime} + {totalTime - {bendTime + firstTime}}
end
# do vibratto for last half
# use special vibratto routine that does not issue note
# just bends
if (vflag)
void vnonote(firstNote, BENDCENTER+totalBendUnits, remainingTime, vsteps, velocity)
return(0)
end
# tie note for remaining time
tie remainingTime
# void printf("bend %d \n",BENDCENTER)
# issue rest to make sure noteoff in effect. this
# is paranoia most likely
rest 0
# put pitchbend wheel at center
bend 0 BENDCENTER
# void dumptime()
end
#
# bend Down requested interval
#
# interval 0..12: max range an octave
riff bendDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vflag, vsteps)
# interval - number of semitones to bend up
int events
int bendIncrement
int totalBendUnits
int pertimeClick
int curincrement
int bendvalue
int elapsedTime
int remainingTime
# make sure pitch bend offset is set at 1 so
# that we use the true MIDI numbers in decimal
poff 1
# don't set interval to 0
if (interval == 0)
void printf("bendUp: invalid 0 interval\n")
final
end
# total number of bend units to cover interval
totalBendUnits = interval * SEMITONEUNITS
# determine per bend event time and how much
# to bend per bend call
# if more time than total bend units according
# to the interval, then divide the time
# by the number of bend units to get the per
# bend call time, otherwise time is 1
if (bendTime > totalBendUnits)
pertimeClick = bendTime / totalBendUnits
bendIncrement = totalBendUnits / pertimeClick
else
bendIncrement = totalBendUnits / bendTime
pertimeClick = 1
end
# void printf("bendIncrement %d\n",bendIncrement)
# void printf("pertimeClick %d\n",pertimeClick)
# void printf("totalBendUnits %d\n",totalBendUnits)
# play note with 0 eventime
# the note lasts "totalTime" time before a noteoff
# is issued
note firstNote firstTime, totalTime velocity
# void dumptime()
bendvalue = BENDCENTER
# start off with pitch bend wheel centered
# take no time to do this
poff 1
bend 0 BENDCENTER
curincrement = bendIncrement
# loop through pitch bend up
elapsedTime = 0
for ( events = 0; events < bendTime; events++)
bend pertimeClick BENDCENTER-curincrement
# void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
curincrement = curincrement + bendIncrement
elapsedTime = elapsedTime + pertimeClick
end
# issue another pitch bend to make sure we
# arrived where we want because for loop
# above may not have arrived precisely
bend 0 BENDCENTER - totalBendUnits
# void printf("%d \n",BENDCENTER+totalBendUnits)
# use bend constant to return pitchbend wheel to center
poff 1
# deterime amount of eventtime remaining
# we may have some slop if the amount of time
# spent playing bends did not equal the bendTime
if (elapsedTime == bendTime)
remainingTime = totalTime - {firstTime + bendTime}
else
remainingTime = {bendTime - elapsedTime} + {totalTime - {bendTime + firstTime}}
end
# do vibratto for last half
# use special vibratto routine that does not issue note
# just bends
if (vflag)
void vnonote(firstNote, BENDCENTER-totalBendUnits, remainingTime, vsteps, velocity)
return(0)
end
# tie note for remaining time
tie remainingTime
# void printf("bend %d \n",BENDCENTER)
# issue rest to make sure noteoff in effect. this
# is paranoia most likely
rest 0
# put pitchbend wheel at center
bend 0 BENDCENTER
# void dumptime()
end
#
# bendUpDown
#
# bend up interval requested
# then bend down
#
riff bendUpDown(firstNote, firstTime, bendTime, totalTime, interval, velocity, vflag, vsteps)
# interval - number of semitones to bend up
int events
int bendIncrement
int totalBendUnits
int pertimeClick
int curincrement
int bendvalue
int elapsedTime
int remainingTime
int firstHalf # first half of time delta
int secondHalf # second half of time delta
# make sure pitch bend offset is set at 1 so
# that we use the true MIDI numbers in decimal
poff 1
# don't set interval to 0
if (interval == 0)
void printf("bendUp: invalid 0 interval\n")
final
end
# split bend timedelta into first half and second
# half and make sure all events are accounted for
# in time
firstHalf = bendTime >> 1
if ({bendTime % 2} != 0)
secondHalf = firstHalf + 1
else
secondHalf = firstHalf
end
# total number of bend units to cover interval
totalBendUnits = interval * SEMITONEUNITS
# determine per bend event time and how much
# to bend per bend call
# if more time than total bend units according
# to the interval, then divide the time
# by the number of bend units to get the per
# bend call time, otherwise time is 1
if (firstHalf > totalBendUnits)
pertimeClick = firstHalf / totalBendUnits
bendIncrement = totalBendUnits / pertimeClick
else
bendIncrement = totalBendUnits / firstHalf
pertimeClick = 1
end
# void printf("bendIncrement %d\n",bendIncrement)
# void printf("pertimeClick %d\n",pertimeClick)
# void printf("totalBendUnits %d\n",totalBendUnits)
# play note with 0 eventime
# the note lasts "totalTime" time before a noteoff
# is issued
note firstNote firstTime,totalTime velocity
# void dumptime()
bendvalue = BENDCENTER
# start off with pitch bend wheel centered
# take no time to do this
poff 1
bend 0 BENDCENTER
curincrement = bendIncrement
# loop through pitch bend up
elapsedTime = 0
for ( events = 0; events < firstHalf; events++)
bend pertimeClick BENDCENTER+curincrement
# void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
curincrement = curincrement + bendIncrement
elapsedTime = elapsedTime + pertimeClick
end
# make sure we got to top
bend 0 BENDCENTER + totalBendUnits
curincrement = totalBendUnits
# now loop down, keep running totals
for ( events = 0; events < secondHalf; events++)
bend pertimeClick BENDCENTER+curincrement
# void printf("%d %d\n",pertimeClick,BENDCENTER+curincrement)
curincrement = curincrement - bendIncrement
elapsedTime = elapsedTime + pertimeClick
end
# issue another pitch bend to make sure we
# arrived where we want because for loop
# above may not have arrived precisely
bend 0 BENDCENTER
# void printf("%d \n",BENDCENTER+totalBendUnits)
# use bend constant to return pitchbend wheel to center
poff 1
# deterime amount of eventtime remaining
# we may have some slop if the amount of time
# spent playing bends did not equal the bendTime
if (elapsedTime == bendTime)
remainingTime = totalTime - {firstTime + bendTime}
else
remainingTime = {bendTime - elapsedTime} + {totalTime - {bendTime + firstTime}}
end
if (vflag)
void vnonote(firstNote, BENDCENTER, remainingTime, vsteps, velocity)
return(0)
end
# tie note for remaining time
tie remainingTime
# void printf("bend %d \n",BENDCENTER)
# issue rest to make sure noteoff in effect. this
# is paranoia most likely
rest 0
# put pitchbend wheel at center
bend 0 BENDCENTER
# void dumptime()
end
# should start with 4 note chord from LLC to LC range
# LLC, LE, LG, LC to LC, E, G, HC octave bend. Fun.
# then play major scale via bends twice.
# finish off with normal C to HC for contrast
#
riff testBendUp()
int i
void printf("C chord bend up\n")
LG 0,w
LE 0,w
LLC 0,w
void bendUp(LC, 0, h, w, 12, 100, 0, 0)
void printf("C scale down twice\n")
for ( i = 0; i < 2; i++)
C q
# up to D
void bendUp(C, 0, e, q, 2, 100, 0, 0)
# up to E
void bendUp(D, 0, e, q, 2, 100, 0, 0)
# up to F
void bendUp(E, 0, e, q, 1, 100, 0, 0)
void bendUp(F, 0, e, q, 2, 100, 0, 0)
void bendUp(G, 0, e, q, 2, 100, 0, 0)
void bendUp(A, 0, e, q, 2, 100, 0, 0)
void bendUp(B, 0, e, q, 1, 100, 0, 0)
end
void printf("C HC reference tones\n")
C q
HC q
end
riff testBendDown()
void printf("bend down: C scale down to G\n")
# C
note C q 127
# C to LB
void bendDown(C, 0, e, q, 1, 127, 0, 0)
# LB to LA
void bendDown(LB, 0, e, q, 2, 127, 0, 0)
# LA to LG
void printf("bend down: LG scale down to LC\n")
void bendDown(LA, 0, e, q, 2, 127, 0, 0)
# LG to LC
void bendDown(LG, 0, e, q, 7, 127, 0, 0)
void printf("C then C to LC\n")
C q
void bendDown(C, 0, q, w, 12, 127, 0, 0)
#
void printf("reference tones LC C \n")
LC q
C q
end
riff testVibratto()
int vsteps
int i
vsteps = 0
for ( i = 0 ; i < 20; i++)
void printf("vsteps %d\n",vsteps)
void vibratto(C, q*3, w, vsteps, 100)
vsteps = vsteps + 10
end
end
riff testguitarRiff()
void bendUp(LG, 2, e+2, q, 2, 110, 1, 70)
void vibratto(LA, q,q, 80, 100)
void vibratto(E, q,q, 60, 100)
void bendUpDown(D, 3, q+e-3, q+e, 2, 110, 0, 0)
void vibratto(C, e, e, 50, 100)
void vibratto(LA, 3*q,3*q, 110, 100)
rest e
void bendUp(LG, 0, e, q+e, 2, 110, 1, 110)
end
riff testBendLib()
void testguitarRiff()
void testBendUp()
void testBendDown()
void testVibratto()
end